package terminal.gui;

import java.util.UUID;

import javax.smartcardio.CardException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

import terminal.utils.BeanProvider;
import core.gui.ValidationWizardPage;
import core.smartCardReader.SmartCardReaderService;
import core.utils.LocatorUriChecker;

@SuppressWarnings("restriction")
public class WzdPgLocatorUri extends ValidationWizardPage {

	private SmartCardReaderService smartCardReaderService = BeanProvider.smartCardReaderService();

	private Label lblRkw;
	private Text txtRkwIp;
	private Text txtRkwPort;
	private Label lblTerminal;
	private Text txtTerminalIp;
	private Text txtTerminalPort;
	private Text txtToken;
	private Button btnCheckToken;

	/**
	 * Create the wizard.
	 * 
	 * @param terminalLocatorUri
	 */
	public WzdPgLocatorUri() {
		super("WzdPgLocatorUri");

		setTitle("Add Locator Uri");
		setDescription("Create new locator Uri to RKW");
	}

	/**
	 * Create contents of the wizard.
	 * 
	 * @param parent
	 */
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);

		setControl(container);
		container.setLayout(new GridLayout(4, false));

		lblRkw = new Label(container, SWT.NONE);
		lblRkw.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 4, 1));
		lblRkw.setText("RKW");

		new Label(container, SWT.NONE).setText("IP:");

		txtRkwIp = new Text(container, SWT.BORDER);
		txtRkwIp.setText("127.0.0.1");
		txtRkwIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		new Label(container, SWT.NONE).setText("Port:");

		txtRkwPort = new Text(container, SWT.BORDER);
		txtRkwPort.setText("8881");
		txtRkwPort.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		lblTerminal = new Label(container, SWT.NONE);
		lblTerminal.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 4, 1));
		lblTerminal.setText("Terminal");

		new Label(container, SWT.NONE).setText("IP:");

		txtTerminalIp = new Text(container, SWT.BORDER);
		txtTerminalIp.setText("127.0.0.1");
		txtTerminalIp.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		new Label(container, SWT.NONE).setText("Port:");

		txtTerminalPort = new Text(container, SWT.BORDER);
		txtTerminalPort.setText("8889");
		txtTerminalPort.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		new Label(container, SWT.NONE).setText("Token:");

		txtToken = new Text(container, SWT.BORDER);
		txtToken.setEditable(false);
		txtToken.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

		btnCheckToken = new Button(container, SWT.NONE);
		btnCheckToken.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		btnCheckToken.setText("Check Token");

		setVerifyListeners();
	}

	private void setVerifyListeners() {
		txtRkwIp.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent arg0) {
				validate();
			}
		});

		txtRkwPort.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent arg0) {
				validate();
			}
		});

		btnCheckToken.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				validate();
			}
		});
	}

	@Override
	protected void validate() {
		String rkwIp = getRkwIp();
		String rkwPort = getRkwPort();
		String terminalIp = getTerminalIp();
		String terminalPort = getTerminalPort();

		String numberPattern = "^-?(\\d)*$";

//		if (MainWindow.isInDebugMode()) {
//			clearErrorState();
//			return;
//		}

		// error
		if (rkwIp.length() == 0) {
			setErrorState("RKW IP cannot be empty.");
			return;
		}
		if (!LocatorUriChecker.isProperIpString(rkwIp)) {
			setErrorState("RKW IP must be of proper format (e.g. 192.168.1.1).");
			return;
		}
		if (rkwPort.length() == 0) {
			setErrorState("RKW Port cannot be empty.");
			return;
		}
		if (!rkwPort.matches(numberPattern)) {
			setErrorState("RKW Port must be a number.");
			return;
		}
		if (terminalIp.length() == 0) {
			setErrorState("Terminal IP cannot be empty.");
			return;
		}
		if (!LocatorUriChecker.isProperIpString(terminalIp)) {
			setErrorState("Terminal IP must be of proper format (e.g. 192.168.1.1).");
			return;
		}
		if (terminalPort.length() == 0) {
			setErrorState("Terminal Port cannot be empty.");
			return;
		}
		if (!terminalPort.matches(numberPattern)) {
			setErrorState("Terminal Port must be a number.");
			return;
		}
		try {
			UUID adminToken = smartCardReaderService.getFirstAdminToken();
			if (adminToken == null) {
				setErrorState("No Administration Token found.");
				return;
			}
			txtToken.setText(adminToken.toString());
		} catch (CardException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// warning
		if (0 <= Integer.valueOf(txtRkwPort.getText()) && Integer.valueOf(txtRkwPort.getText()) <= 1023) {
			setWarningState("It is discouraged to use a Port number between 0 and 1023.");
			return;
		}
		if (0 <= Integer.valueOf(txtTerminalPort.getText()) && Integer.valueOf(txtTerminalPort.getText()) <= 1023) {
			setWarningState("It is discouraged to use a Port number between 0 and 1023.");
			return;
		}

		// ok
		clearErrorState();
	}

	@Override
	protected void update() {
	}

	protected String getRkwIp() {
		return txtRkwIp.getText().trim();
	}

	protected String getRkwPort() {
		return txtRkwPort.getText().trim();
	}

	protected String getTerminalIp() {
		return txtTerminalIp.getText().trim();
	}

	protected String getTerminalPort() {
		return txtTerminalPort.getText().trim();
	}

	public UUID getCommunicationToken() {
		try {
			return smartCardReaderService.getFirstAdminToken();
		} catch (CardException e) {
			e.printStackTrace();
			return null;
		}
	}

}
